<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>SSE聊天示例</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
    }

    #chat-container {
      margin-top: 20px;
    }

    #message-input {
      width: 70%;
      padding: 10px;
      font-size: 16px;
    }

    #send-button {
      width: 25%;
      padding: 10px;
      font-size: 16px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
    }

    #chat-history {
      height: 400px;
      border: 1px solid #ccc;
      margin-top: 20px;
      padding: 10px;
      overflow-y: auto;
      background-color: #f9f9f9;
    }

    .message {
      margin-bottom: 10px;
      padding: 5px;
      white-space: pre-wrap; /* 保留空白符序列，但是正常地进行换行 */
    }

    .user-message {
      background-color: #e3f2fd;
      text-align: right;
    }

    .assistant-message {
      background-color: #f5f5f5;
    }

    .processing-message {
      color: #888;
      font-style: italic;
    }

    /* 新增图片样式 */
    .image-message {
      margin: 10px 0;
      text-align: center;
    }

    .image-message img {
      max-width: 100%;
      max-height: 300px;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    }

    .user-image {
      text-align: right;
    }

    .assistant-image {
      text-align: left;
    }
  </style>
</head>
<body>
<h1>SSE 聊天示例</h1>

<div id="chat-container">

  <div id="chat-history"></div>
  <input type="text" id="message-input" placeholder="请输入消息...">
  <button id="send-button" onclick="sendMessage()">发送</button>
</div>
<script>
  let eventSource = null;

  function sendMessage() {
    const input = document.getElementById('message-input');
    const message = input.value.trim();

    if (message) {
      // 关闭之前的连接（如果存在）
      if (eventSource) {
        eventSource.close();
      }

      // 创建新的SSE连接
      eventSource = new EventSource(`/ask?message=${encodeURIComponent(message)}`);

      // 首先显示用户消息
      addMessageToChat(message, 'user');

      input.value = '';
      let assistantMessage = '';
      // 用于保存"思考中…"占位节点的引用
      let processingNode = null;

      // 重置全局引用，确保每次新消息都创建新的DOM节点
      window.currentAssistantNode = null;

      // 处理不同事件类型
      eventSource.addEventListener('processing', function(event) {
        // 仅创建一次占位消息
        if (!processingNode) {
          processingNode = addMessageToChat(event.data || '思考中…', 'processing');
        }
      });

      eventSource.addEventListener('message', function(event) {
        // 第一次收到内容时，把占位消息替换为 AI 消息
        removeProcessingNode();

        if (!assistantMessage) {
          // 第一条内容：新建 AI 消息节点
          assistantMessage = event.data;
          const messageElement = addMessageToChat(assistantMessage, 'assistant');
          // 保存引用以便后续追加
          window.currentAssistantNode = messageElement;
        } else {
          // 继续追加
          assistantMessage += event.data;
          if (window.currentAssistantNode) {
            window.currentAssistantNode.textContent = assistantMessage;
          }
        }
        // 滚动到最新消息
        scrollToBottom();
      });

      // 新增：处理图片事件
      eventSource.addEventListener('image', function(event) {
        // 移除占位消息（如果存在）
        removeProcessingNode();

        // 重置当前消息节点，因为图片是独立的消息
        window.currentAssistantNode = null;
        assistantMessage = '';

        // 添加图片到聊天记录
        addImageToChat(event.data, 'assistant');
      });

      // 新增：处理图片URL事件
      eventSource.addEventListener('image-url', function(event) {
        // 移除占位消息（如果存在）
        removeProcessingNode();

        // 重置当前消息节点，因为图片是独立的消息
        window.currentAssistantNode = null;
        assistantMessage = '';

        // 添加图片到聊天记录
        addImageUrlToChat(event.data, 'assistant');
      });

      eventSource.addEventListener('complete', function(event) {
        if (event.data === '[DONE]') {
          eventSource.close();
          // 清理引用
          window.currentAssistantNode = null;
        }
      });

      eventSource.addEventListener('error', function(event) {
        console.error("SSE错误:", event);
        eventSource.close();
        // 移除占位节点（如果还在）
        removeProcessingNode();
        const finalText = assistantMessage ? assistantMessage + "\n[连接错误]" : "[连接错误]";
        if (window.currentAssistantNode) {
          window.currentAssistantNode.textContent = finalText;
        } else {
          addMessageToChat(finalText, 'assistant');
        }
      });

      eventSource.onerror = function (err) {
        console.error("SSE错误:", err);
        eventSource.close();
        removeProcessingNode();
        if (!assistantMessage) {
          addMessageToChat("[连接错误]", 'assistant');
        }
        if (window.currentAssistantNode) {
          window.currentAssistantNode.textContent = "[连接错误]";
        }
      };
    }
  }

  function removeProcessingNode() {
    if (processingNode) {
      processingNode.remove();
      processingNode = null;
    }
  }

  function addMessageToChat(content, sender) {
    const chatHistory = document.getElementById('chat-history');
    const messageElement = document.createElement('div');
    messageElement.className = `message ${sender}-message`;
    messageElement.textContent = content;

    // 将新消息追加到聊天历史记录的末尾
    chatHistory.appendChild(messageElement);

    // 滚动到最新消息
    scrollToBottom();

    return messageElement;
  }

  // 新增：添加Base64图片到聊天记录
  function addImageToChat(base64Data, sender) {
    const chatHistory = document.getElementById('chat-history');
    const imageContainer = document.createElement('div');
    imageContainer.className = `image-message ${sender}-image`;

    const img = document.createElement('img');
    img.src = `data:image/png;base64,${base64Data}`;
    img.alt = '图片';

    imageContainer.appendChild(img);
    chatHistory.appendChild(imageContainer);

    // 滚动到最新消息
    scrollToBottom();

    return imageContainer;
  }

  // 新增：添加图片URL到聊天记录
  function addImageUrlToChat(imageUrl, sender) {
    const chatHistory = document.getElementById('chat-history');
    const imageContainer = document.createElement('div');
    imageContainer.className = `image-message ${sender}-image`;

    const img = document.createElement('img');
    img.src = imageUrl;
    img.alt = '图片';

    imageContainer.appendChild(img);
    chatHistory.appendChild(imageContainer);

    // 滚动到最新消息
    scrollToBottom();

    return imageContainer;
  }

  function scrollToBottom() {
    const chatHistory = document.getElementById('chat-history');
    chatHistory.scrollTop = chatHistory.scrollHeight;
  }

  // 支持回车发送
  document.getElementById('message-input').addEventListener('keypress', function (e) {
    if (e.key === 'Enter') {
      sendMessage();
    }
  });
</script>
</body>
</html>